﻿#include <gl/glew.h>
#include <gl/glut.h>
#include <gl/glu.h>
#include <cstdlib>

#include "ilUtil.h"

/*
  two tex
  opt: module
  a plane( splite as two triangles )
  glXXXPointer
*/

static const int QUIT_VALUE(99);

static GLfloat vertex[]=
  {
    -0.5f, -0.5f, 0,
    0.5f, -0.5f, 0,
    0.5f, 0.5f, 0,
    -0.5, 0.5f, 0
  };

//static GLfloat color[]=
//{
//  1.0f, 0, 0,
//  0,   0, 1.0f,
//  0,    1.0f, 0,
//  1.0f, 1.0f, 1.0f 
//};

static GLfloat coord[]=
{
  0, 0,
  1.0f, 0,
  1.0f, 1.0f,
  0, 1.0f
};

static GLushort index[]=
  {
    3,0,1,2
  };

static GLuint tex[2];

static void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glLoadIdentity();

  glClientActiveTexture(GL_TEXTURE0);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glBindTexture(GL_TEXTURE_2D, tex[0]);
  glTexCoordPointer(2, GL_FLOAT, 0, coord);
	//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	//glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
	//glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
	//glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);

  glClientActiveTexture(GL_TEXTURE1);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glBindTexture(GL_TEXTURE_2D, tex[1]);
  glTexCoordPointer(2, GL_FLOAT, 0, coord);
	//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	//glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
	//glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
	//glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
	//glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
	//glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);


  glTranslatef(0, 0, -1.5f);
  glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, index);

  glutSwapBuffers();
}

static void reshape(int w, int h)
{
  glViewport(0, 0, w, h);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  // arg1: angle of y axis
  // arg2: 纵横比
  // arg3: near plane pos
  // arg4: far plane pos
  gluPerspective(50.0f, (double)w/(double)h, 1.0f, 10.0f);

  glMatrixMode(GL_MODELVIEW);
}

static void mainMenuCB(int value)
{
  if( value == QUIT_VALUE )
    exit(0);
}


static void init()
{
  glDisable(GL_DITHER);

  glPolygonMode(GL_FRONT, GL_FILL);
  glPolygonMode(GL_BACK, GL_LINE);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, 0, vertex);
  //glEnableClientState(GL_COLOR_ARRAY);
  //glColorPointer(3, GL_FLOAT, 0, color);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, 0, coord);

  ILuint imgSword, imgLight;
  ilInit();

  ilGenImages(1, &imgSword);
  ilBindImage(imgSword);

  ilEnable(IL_ORIGIN_SET);
  ilSetInteger(IL_ORIGIN_MODE, IL_ORIGIN_LOWER_LEFT);
  ilLoad(IL_PNG, "../media/sword.png");
  ImageInfo info = ImageInfo::Get();

    glGenTextures(2, tex);

    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, info.format, info.w, info.h, 0,
      info.format, info.componentDataType, info.pData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  ilDeleteImages(1, &imgSword); // can release image data in memory, because submit to VRAM

  ilGenImages(1, &imgLight);
  ilBindImage(imgLight);

  ilEnable(IL_ORIGIN_SET);
  ilSetInteger(IL_ORIGIN_MODE, IL_ORIGIN_LOWER_LEFT);
  ilLoad(IL_PNG, "../media/light.png");
  info = ImageInfo::Get();

  glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, info.format, info.w, info.h, 0,
      info.format, info.componentDataType, info.pData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD/*GL_MODULATE*/);
  ilDeleteImages(1, &imgLight); // can release image data in memory, because submit to VRAM

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // 关闭余下的tex unit
    GLint texLimit;
    glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texLimit);
    for(int i=2; i<texLimit; ++i)
    {
      glActiveTexture(GL_TEXTURE0 + i);
      glDisable(GL_TEXTURE_2D);
    }

  glClearColor(0, 0, 0, 0);

  glutDisplayFunc(display);
  glutReshapeFunc(reshape);

  int mainMenu = glutCreateMenu(mainMenuCB);
  glutAddMenuEntry("Quit", QUIT_VALUE);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

static void Term()
{
  if(tex[0])
  {
    glDeleteTextures(2, tex);
  }
}

int main(int argc, char* argv[])
{
  glutInit(&argc, argv);

  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize(640, 480);
  glutCreateWindow("Simple Queue");

  glewInit();

  init();

  glutMainLoop();

  Term();

  return 0;
}
